﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Sinacor.Infra.Common
{
    public class PropertyValueType
    {
        public PropertyValueType()
        {
        }

        public PropertyValueType(Object propertyValue, Type propertyType)
        { 
            this.PropertyValue = propertyValue;
            this.PropertyType = propertyType;
        }

        public Object PropertyValue { get; set; }
        public Type PropertyType { get; set; }
    }

    public static class ObjectExtensionMethods
    {
        /// <summary>
        /// Recuperar os valores/tipos de uma lista de propriedades de um objeto
        /// </summary>
        /// <param name="item"></param>
        /// <param name="properties"></param>
        /// <returns></returns>
        public static List<PropertyValueType> GetPropertyInfo(this Object item, IEnumerable<string> properties)
        {
            if (properties == null)
                throw new ArgumentNullException("properties");

            List<PropertyValueType> propertiesInfo = new List<PropertyValueType>();

            foreach (string property in properties)
            {
                PropertyValueType valueType = GetPropertyInfo(item, property);

                if (valueType != null)
                    propertiesInfo.Add(valueType);
            }

            return propertiesInfo;

        }

        /// <summary>
        /// Recuperar o valor/tipo de uma propriedade de um objeto
        /// </summary>
        /// <param name="item"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static PropertyValueType GetPropertyInfo(this Object item, string property)
        {
            if (string.IsNullOrEmpty(property))
                return null;

            string[] fieldsName = property.Split('.');
            Type propType = item.GetType();
            PropertyInfo propInfo = null;
            object propValue = item;

            foreach (string field in fieldsName)
            {
                propInfo = propType.GetProperty(field);

                if (propInfo != null)
                {
                    propType = propInfo.PropertyType;
                    propValue = propInfo.GetValue(propValue, null);

                    if (propType == null || propValue == null)
                        break;
                }
                else
                {
                    propType = null;
                    propValue = null;
                    break;
                }
            }

            if (propType != null)
            {
                return new PropertyValueType(propValue, propType);
            }

            return null;
        }
    }
}
